/*
**  File: AquaTypes.h
*/
#ifndef TYPESh
#define TYPESh

#ifndef GENERALh
#include "General.h"
#endif
#ifndef MACROSh
#include "AquaMacros.h"
#endif

typedef char    Typnam[size_TYPNAM];    /* used in programs as ..    */
typedef char    Resid[size_RESID];      /* .. \0 terminated strings  */
typedef char    ID[size_ID];            /* ID is not \0 terminated ! */
                                        /* and is blank padded at right */

enum { ext_to_int, int_to_ext };
 
enum { use_int, use_ext, use_both };
 
enum { restsel_both, restsel_one };

enum { empty_set, created_set, part_set, complete_set };

enum { crd_list, crd_aqua,  crd_dummy, crd_pdb, crd_star, crd_pdbn, crd_pdbx, 
       crd_pdbm, crd_pdbmr, crd_biosym };

enum { item_disman, item_disgeo, item_diana, item_xplor, item_xplori, 
       item_biosym, item_whatif, item_nmrstar, item_dgo,  
       item_local, item_user, item_copy, item_aqua };

enum { item_assign, item_average, item_sum, item_satur };

typedef enum { status_ok, end_of_data, eof_err, read_err }
Status;

typedef enum { inf_unktyp, inf_normal, inf_extended, inf_multi_model }
DistinfTyp;

typedef enum { dd_unktyp, dd_inf_normal, dd_inf_extended, 
               dd_val_normal, dd_val_extended }     /* add class types */
DistdataTyp;

typedef enum { undef_rng=0, intra_rng=1, seq_rng=2, medium_rng=3, 
               long_rng=4, inter_rng=5 }
ContactRange;               /* make sure that the enum's can be used as
                               sequential indices */
                            /* also see num_CONTACTRANGE macro */

typedef enum { undef_data,  
           dummy_str_data,  orig_str_data,  sel_str_data,
            pseu_str_data, explo_str_data,   
	      assign_data, noe_compl_data,  atomlib_data, 
             noe_cnt_data,   noe_inf_data,  noe_val_data,  noe_rst_data, 
	     noe_err_data,  noe_infl_data, noe_vall_data, noe_star_data, 
              ss_cnt_data,    ss_inf_data,   ss_val_data,   ss_rst_data,  
	      ss_err_data,   ss_infl_data,  ss_vall_data,  ss_star_data, 
              hb_cnt_data,    hb_inf_data,   hb_val_data,   hb_rst_data,  
	      hb_err_data,   hb_infl_data,  hb_vall_data,  hb_star_data, 
             dis_cnt_data,   dis_inf_data,  dis_val_data,  dis_rst_data, 
	     dis_err_data,  dis_infl_data, dis_vall_data, dis_star_data } 
Qtyp;

typedef enum { no_fil_type,        dummy_type,   set_type, 
                  ass_type, completeness_type, atlib_type, 
                 rcnt_type,         rvio_type, 
                 dinf_type,         dval_type,  drst_type, star_type, 
                  pdb_type,         pdbn_type,  pdbx_type, pdbm_type, 
	        pdbmr_type,       biosym_type, 
	   aqua_drfil_type,    dgo_drfil_type, 
          diana_drfil_type,  xplor_drfil_type,biosym_drfil_type, 
        nmrstar_drfil_type }
Filtyp;

typedef enum { bnd_ok,     bnd_sml_lo, bnd_big_up, bnd_incomp, 
               bnd_noatom, bnd_sameat, bnd_incompd, 
               bnd_upper,  bnd_lower,  bnd_uplo,   bnd_uld }
Bndstat;

typedef struct
{
    Qtyp    type;
    char    *file_selector;
    char    *type_text;
    Filtyp  file_type;
}
Aquarec;

typedef struct
{
    Filtyp  type;
    char    *type_name;
    char    *extension;
}
Filerec;

typedef struct
{
    ContactRange  type;
    char          *type_name;
    char          *star_type_name;
}
Contactrec;

typedef struct
{
    float   x;
    float   y;
    float   z;
}
Coord;

typedef struct
{
    int      res_num_new;   /* new, unique, sequential residue number */
    int      res_num_orig;
    ID       chain;
    ID       atom_int;
    ID       atom_ext;
/* Left aligned, 2 chars, 1st upper, 2nd lower case or 2 empty spaces if undef*/
    ID       atom_element_symbol; 
    ID       res_nam;
    char     res_insert;
    Resid    res_id;
}
Atom;

typedef Atom *Atomptr;

typedef struct
{
    int     pseudo_typ;
    int     num_form;
    int     res_num_orig;
    ID      chain;
    ID      res_nam;
    ID      pseudo_nam;
    ID      form_nam[max_PSFORM];
    char    res_insert;
    Resid   res_id;
}
Psatom;

typedef struct
{
    int     idx;     /* index of atom in coordinate list */
    int     res;     /* residue number (in new, sequential list) */
}
Distidx;

typedef struct
{
    int      dtype;   /* restraint type (not yet used) */
    int      atype_A; /* pseudo atom type for atom A */
    int      atype_B; /* pseudo atom type for atom B */
    int      count_A; /* number of "equivalent atoms" for atom A */
    int      count_B; /* number of "equivalent atoms" for atom B */
    int      ass_A;   /* index in A of atom assigned in input; 0 <= ass_A < count_A */
    int      ass_B;   /* index in B of atom assigned in input; 0 <= ass_B < count_B */
    Distidx  *A;      /* the list of "equivalent atoms" for atom A; pseudo is last */
    Distidx  *B;      /* the list of "equivalent atoms" for atom B; pseudo is last */
}
Distinfl;

typedef struct
{
    int     dtype;     /* restraint type (now used in ClassifyRestraints) */
    int     idx_A;     /* index of atom A in coordinate list */
    int     idx_B;     /* index of atom B in coordinate list */
    int     res_A;     /* residue number (in new, sequential list) of atom A */
    int     res_B;     /* residue number (in new, sequential list) of atom B */
}
Distinf;

typedef struct
{
    float   lo_bnd;
    float   up_bnd;
    float   dist;
    char    typ_bnd;    /* [ulbB]: indicates type/presence of bounds */
}
Distrst;

typedef float Distval;

typedef struct
{
    Distval  *values;  /* list of distances calculated for one restraint */
    int      count;    /* number of distances calculated for one restraint */
                       /* (one distance for every assignment) */
}
Distvall;

typedef struct distdatadesc DistdataDesc;
struct distdatadesc
{
    DistdataDesc   *next;
    DistdataDesc   *related;
    void           *data;
    DistdataTyp    type;
};

typedef struct
{
    DistdataDesc   *fst_desc;
    DistdataDesc   *lst_desc;
    int            count;
}
DistdataList;

typedef struct
{
    Atom     atom_A;
    Atom     atom_B;
    float    lo_bnd;
    float    up_bnd;
    float    dist;
    int      idx_A;
    int      idx_B;
    Boolean  keep;
    Bndstat  stat;
}
DRestraint;

typedef struct
{
    DRestraint  *list;
    int         struc_count;
    int         dist_count;
}
DRList;

typedef struct
{
    int     struc_num;
    int     fil_struc_num;  /* the sequence number on the original file */
}
Model;

typedef struct
{
    int      atom_count;
    int      res_num_new;   /* new, unique, sequential residue number */
    int      res_num_orig;
    ID       chain;
    ID       res_nam;
    char     res_insert;
    Resid    res_id;
    Atomptr  *atomptrs;
    int      *atomidxs;
}
Residue;

typedef struct
{
    Atom    *atoms;
    Residue *residues;
    int     atom_count;
    int     res_count;
    Filtyp  inp_filtyp;     /* the type of the original file */
    Filnam  inp_filnam;     /* the name of the original file */
    Card    ident;
}
Mol;

typedef struct struc Struc;
struct struc
{
    Struc   *next_struc;
    Mol     *struc_mol;     /* a name table per struc (if needed) */
    Coord   *coords;
    int     atom_count;
    int     struc_num;      /* sequential model number, starting at 1 */
    int     fil_struc_num;  /* the sequence number on the original file */
    Filnam  inp_filnam;     /* the name of the original file */
    Card    ident;
};

typedef struct strucset Strucset;
struct strucset
{
    Mol      *molecule;
    Struc    *fst_struc;
    Struc    *lst_struc;
    int      struc_count;
    int      atom_count;     /* used atoms */
    int      atom_count_mem; /* allocated atoms - if 0 use atom_count */
    Boolean  mapped;         /* internal names set? */
    Boolean  onemap;         /* one name map for all models? */
    Qtyp     type;
    Card     ident;
    Card     derived;
    Filnam   filnam;         /* the name of the strucset file */
    Typnam   name;           /* the name of the strucset */
};

typedef struct setlist Setlist;
struct setlist
{
    Strucset *setptr;
    Setlist  *link;
};

                             /* a pointer to the <FindAtom> functions */
typedef Atom *(*FctFindAt)( int *, Atom *, Mol *, const int, const Boolean );

#endif
